
#include "audio.h"
#include "audio_set.h"
#include "script/scripthelper.h"

#include "ui/ui_manager.h"
#include "util/log.h"				// log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"		    

using namespace audio;
using namespace script;


AudioSet::AudioSet() :
	num::NamedSet<AudioSubset*>()
{

}

AudioSet::~AudioSet()
{
	ClearSet();
}

/*
void AudioSet::Load(const std::string& File)
{
	LuaPlus::LuaState*	pScript = ScriptHelper::CreateLuaState();
	if (!ScriptHelper::DoFile(*pScript, File))
	{
		_LOG(MSG_ERROR, "Unable to load audio-set " << File << "!");
		 LuaPlus::LuaState::Destroy( pScript );
		return ;
	}
	// fix RAII bug
	{
		LuaPlus::LuaObject	SFX_Set = ScriptHelper::GetObj(*pScript, "SoundBank");
		if (SFX_Set.IsTable())
		{
			for (int i = 0; i<SFX_Set.GetTableCount(); i++)
			{
				LuaPlus::LuaObject	SFX = SFX_Set.GetByIndex(i+1);
				if (SFX.IsTable())
				{
					std::string			Name  = ScriptHelper::GetTableString(SFX, "Name", "");
					LuaPlus::LuaObject	Files = SFX.GetByName("Files");
					LuaPlus::LuaObject	Bias = SFX.GetByName("Bias");
					if (Files.IsTable() && !Name.empty())
					{
						AudioSubset*	pSet = new AudioSubset;
						pSet->Name = Name;
						pSet->LastPlayed  = NULL;
						for (int j=0; j<Files.GetTableCount(); j++)
						{
							if (Files.GetByIndex(j+1).GetString())
							{
								AudioSetFile	AF;
								AF.Filename = Files.GetByIndex(j+1).GetString();
								AF.Handle   = AUDIO.LoadSound(AF.Filename);

						
								if (Bias.IsTable() && Bias.GetByIndex(j+1).IsNumber())
								{
									AF.SoundBias = Bias.GetByIndex(j+1).GetFloat();
									UTIL_CLAMP(AF.SoundBias, 0.1f, 1.0f);
								}
								pSet->AudioFiles.push_back(AF);
							}
						}
						AddElement(pSet->Name, pSet);
					}
				}
			}
		}
	}
	// IMPORTANT: CANNOT DESTROY BEFORE WE'RE OUT OF THAT IF STATEMENT!
	LuaPlus::LuaState::Destroy( pScript );
}
*/

void AudioSet::Load(const std::string& File)
{
	LuaPlus::LuaState*	pScript = ScriptHelper::CreateLuaState();
	if (!ScriptHelper::DoFile(*pScript, File))
	{
		_LOG(MSG_ERROR, "Unable to load audio-set " << File << "!");
		 LuaPlus::LuaState::Destroy( pScript );
		return ;
	}
	// fix RAII bug
	{
		LuaPlus::LuaObject	SFX_Set = ScriptHelper::GetObj(*pScript, "SoundBank");
		if (SFX_Set.IsTable())
		{
			for (int i = 0; i<SFX_Set.GetTableCount(); i++)
			{
				LuaPlus::LuaObject	SFX = SFX_Set.GetByIndex(i+1);
				if (SFX.IsTable())
				{
					std::string			Name		= ScriptHelper::GetTableString(SFX, "Name", "");
					std::string			Filename	= ScriptHelper::GetTableString(SFX, "Filename", "");
					float				SoundBias	= ScriptHelper::GetTableFloat(SFX, "SoundBias", 1);
					bool				Repeat	= ScriptHelper::GetTableBool(SFX, "Repeat");
					AudioSubset*		pSet = GetElement(Name);
					if (!pSet)
					{	
						pSet = new AudioSubset;
						pSet->Name = Name;
						AddElement(Name, pSet);
					}
					AudioSetFile	AF;
					AF.Filename  = Filename;
					AF.SoundBias = SoundBias;
					AF.Handle   = AUDIO().LoadSound(AF.Filename,  Repeat);
					AF.Size		= AUDIO().GetFileSize(AF.Handle);
					UTIL_CLAMP(AF.SoundBias, 0.1f, 1.0f);
					pSet->AudioFiles.push_back(AF);					
				}
			}
		}
	}
	// IMPORTANT: CANNOT DESTROY BEFORE WE'RE OUT OF THAT IF STATEMENT!
	LuaPlus::LuaState::Destroy( pScript );
}


AudioHandle		AudioSet::PlayEffect(const std::string& Name)
{
	AudioSubset*	pSet = GetElement(Name);
	if (pSet)
	{
		int Count = pSet->AudioFiles.size();
		int	Index = (int)(rand()) % Count;
		if (!pSet->AudioFiles[Index].Handle)
		{
			//_LOG(MSG_WARNING, "SFX: error playing sample " << Name << ", couldn't find file " << pSet->AudioFiles[Index].Filename);
			return -1;
		}
		if (AUDIO().IsPlaying(pSet->LastPlayed))
		{
//			return NULL;	// already playing
		}
		pSet->LastPlayed = AUDIO().PlaySFX(pSet->AudioFiles[Index].Handle, pSet->AudioFiles[Index].SoundBias);
		return pSet->LastPlayed;
	} else
	{
		//_LOG(MSG_WARNING, "SFX: Couldn't find sound file " << Name);
	}

	return -1;
}
